import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/**
 *
 * @author kaszubm9
 */
public class Timetables{

    public static int[][] getTimetableArray(int route, TimetableInfo.timetableKind kind, int noOfStops) {
        int[] services=TimetableInfo.getServices(route, kind);
        int[][] serviceTimes=new int[services.length][noOfStops];
        int bug=services[0];
        for (int j = 0; j < services.length; j++){
             if(route==67 || route==68)
                 serviceTimes[j]=fill358(serviceTimes[j], services[j]-bug, route, kind);
             else if(route==66)
                 serviceTimes[j]=fill384(serviceTimes[j], services[j]-bug, route, kind);
             else
                 serviceTimes[j]=TimetableInfo.getServiceTimes(route, kind, services[j]-bug);
        }
        return serviceTimes;
    }


 /**
 *   This class is not intended to be instantiated
 */
    public Timetables() {
    }
    /**
     * Method called by showTimetable
     * @param stopsNames
     * @param route
     * @param kind
     * @return
     */
    private static String[] fillTimetableWithTimes(String[] stopsNames, int route,
            TimetableInfo.timetableKind kind) {

        int hour, minute;
        int[] services=TimetableInfo.getServices(route, kind);
        int[][] serviceTimes=new int[services.length][stopsNames.length];
        int bug=services[0];
        for (int j = 0; j < services.length; j++){
             if(route==67 || route==68)
                 serviceTimes[j]=fill358(serviceTimes[j], services[j]-bug, route, kind);
             else if(route==66)
                 serviceTimes[j]=fill384(serviceTimes[j], services[j]-bug, route, kind);
             else
                 serviceTimes[j]=TimetableInfo.getServiceTimes(route, kind, services[j]-bug);
             for (int i=0; i < serviceTimes[j].length; i++){
                 hour=DateValidation.getHour(serviceTimes[j][i]);
                 if(hour==99)
                     stopsNames[i]=stopsNames[i] + "-------";
                 else{
                     minute=DateValidation.getMinuts(serviceTimes[j][i]);
                     stopsNames[i]=fill(stopsNames[i], hour, minute);

                 }//else
            }//for
        }//for

        return stopsNames;
    }

    /**
     * Called by fillTimetableWithTimes
     * @param stopName
     * @param hour
     * @param minute
     * @return
     */
    public static String fill(String stopName, int hour, int minute) {
        if(minute<10 && hour<10)
            stopName=stopName + "   " +  hour + ":0" + minute;
        else if(minute<10 && hour>=10)
            stopName=stopName + "  " + hour + ":0" + minute;
        else if(minute>=10 && hour<10)
            stopName=stopName + "   " + hour + ":" + minute;
        else
            stopName=stopName + "  " + hour + ":" + minute;
        return stopName;
    }

    /**
     * Called by fillTimetableWithTimes
     * @param serviceTimes
     * @param serviceId
     * @param route
     * @param kind
     * @return
     */
    private static int[] fill358(int[] serviceTimes, int serviceId, int route, TimetableInfo.timetableKind kind){
        //1 service of 4,9,tree services of 10 and one service of 12
        int[] times=TimetableInfo.getServiceTimes(route, kind, serviceId);
        serviceTimes=new int[13];
        if(route==67)
            serviceTimes=find358outTimes(serviceTimes, times);
        else if(route==68)
            serviceTimes=find358backTimes(serviceTimes, times);
        return serviceTimes;
    }

    private static int[] fill384(int[] serviceTimes, int serviceId, int route, TimetableInfo.timetableKind kind){
        //1 service of 4,9,tree services of 10 and one service of 12
        int[] times=TimetableInfo.getServiceTimes(route, kind, serviceId);
        serviceTimes=new int[9];
        int noOfStops=times.length;
        for (int i = 0; i < 9; i++) {
              if(noOfStops==9)
                  serviceTimes[i]=times[i];
              else if(noOfStops==3){
                  if(i<6)
                     serviceTimes[i]=99*60;
                  else
                     serviceTimes[i]=times[i-6];
              }
              else if(noOfStops==8)
                  if(i==8)
                     serviceTimes[i]=99*60;
                  else
                     serviceTimes[i]=times[i];
              else if(noOfStops==2)
                  if(i<7)
                     serviceTimes[i]=99*60;
                  else
                     serviceTimes[i]= times[i-7];
              else
                  serviceTimes[i]= times[i];

        }
        return serviceTimes;
    }
    /**
     * Called by fill358
     * @param serviceTimes
     * @param times
     * @return
     */
    private static int[] find358outTimes(int[] serviceTimes, int[] times) {
        int noOfStops=times.length;
        for (int i = 0; i < 13; i++) {
                if(noOfStops==10){
                     if(i<3)
                         serviceTimes[i]=99*60;
                     else
                         serviceTimes[i]=times[i-3];
                 }
                 else  if(noOfStops==4){
                     if(i<3)
                         serviceTimes[i]=99*60;
                      if(i>=3 && i<7)
                         serviceTimes[i]=times[i-3];
                        else
                          serviceTimes[i]=99*60;
                    }
                else if(noOfStops==9){
                         if(i<3 || i==6)
                              serviceTimes[i]=99*60;
                         else if(i>=3 && i<6)
                              serviceTimes[i]=times[i-3];
                         else
                              serviceTimes[i]=times[i-4];
                 }
                 else if(noOfStops==12){
                    if(i<6)
                        serviceTimes[i]=times[i+2];
                    else if(i==6)
                        serviceTimes[i]=99*60;
                    else if(i>10)
                        serviceTimes[i]=times[i-11];
                    else
                        serviceTimes[i]=times[i-1];
                 }
           }//for
        return serviceTimes;
    }

    /**
     * Called by fill358
     * @param serviceTimes
     * @param times
     * @return
     */
    private static int[] find358backTimes(int[] serviceTimes, int[] times) {
        int noOfStops=times.length;
        for (int i = 0; i < 13; i++) {
                if(noOfStops==10){
                     if(i<3)
                         serviceTimes[i]=99*60;
                     else
                         serviceTimes[i]=times[i-3];
                 }
                 else  if(noOfStops==4){
                     if(i<6)
                         serviceTimes[i]=99*60;
                      if(i>=6 && i<10)
                         serviceTimes[i]=times[i-6];
                      else
                          serviceTimes[i]=99*60;
                    }
                else if(noOfStops==9){
                         if(i>9 || i==6)
                              serviceTimes[i]=99*60;
                         else if(i<6)
                              serviceTimes[i]=times[i];
                         else
                              serviceTimes[i]=times[i-1];
                 }
                 else if(noOfStops==12){
                    if(i<6)
                        serviceTimes[i]=times[i];
                    else if(i==6)
                        serviceTimes[i]=99*60;
                    else
                        serviceTimes[i]=times[i-1];
                 }
           }//for
        return serviceTimes;
    }


  /**
   * Method to print full timetables for a particular route ex. 358out on weekday
   * is called after pressing 358out button for weekday on interface
   * @param route
   * @param kind
   */

    public static void showTimetable(int route, TimetableInfo.timetableKind kind){
        String[] stopsNames=NameInfo.getStopNames(route);
        stopsNames=fillTimetableWithTimes(stopsNames, route, kind);
        printToFile(stopsNames, route, kind);
   }

    /**
     * Method called by showTimetable
     * @param stopsNames
     * @param route
     * @param kindgetsource
     */

    private static void printToFile(String[] stopsNames, int route,
            TimetableInfo.timetableKind kind){
        try{
         // Create file
        String routeName=BusStopInfo.getRouteName(route);
        FileWriter fstream = new FileWriter("routetimetables.txt");
        BufferedWriter out = new BufferedWriter(fstream);
        out.write("LINE " + routeName + ": ");
        out.newLine();
        out.newLine();
        out.write(""+kind);
        out.newLine();
        out.newLine();
        for (int i = 0; i < stopsNames.length; i++) {
          out.write(stopsNames[i]);
          out.newLine();
        }
        out.close();
        }
        catch (IOException e){//Catch exception if any
             System.err.println("Error: " + e.getMessage());
        }

    }
 /**
  *Use by interface to print the result of passenger search
  * @param bestRoute
  */
    public static void printPassengerChoice(Journey bestRoute){
        try{
             // Create file
            String routeName=BusStopInfo.getRouteName(bestRoute.getRoute());
            FileWriter fstream = new FileWriter("passengerResult.txt");
            BufferedWriter out = new BufferedWriter(fstream);
            out.write("LINE: "+routeName);
            out.newLine();
            out.newLine();
            int atime=bestRoute.getDepoTime();
            String timef=fill("", DateValidation.getHour(atime) , DateValidation.getMinuts(atime));
            out.write("Departure:  "+timef +"   "+BusStopInfo.getFullName(bestRoute.getStartStop()));
            out.newLine();
            out.newLine();
            int dtime=bestRoute.getArrivalTime();
            String timed=fill("", DateValidation.getHour(dtime) , DateValidation.getMinuts(dtime));
            out.write("Arrrival:  "+timed +"   "+BusStopInfo.getFullName(bestRoute.getEndStop()));
            out.newLine();
            out.newLine();
            out.write("Number of middle bus stops:  "+bestRoute.getNoOfBusStopsBetween());
            out.close();
        }
        catch (IOException e){//Catch exception if any
             System.err.println("Error: " + e.getMessage());
        }
    }

        static void printNoJourney(){
            try{
                FileWriter fstream = new FileWriter("passengerResult.txt");
                BufferedWriter out = new BufferedWriter(fstream);
                out.write("There is no way you can get there with our services,");
                out.newLine();
                out.write("Try other combinations of bus stops from given area");
                out.close();
            }
            catch (IOException e){//Catch exception if any
              System.err.println("Error: " + e.getMessage());
             }
        }



        static void printPassengerChoice(Journey firstOptimal, Journey secondOptimal) {
        try{
             // Create file
            String routeName=BusStopInfo.getRouteName(firstOptimal.getRoute());
            FileWriter fstream = new FileWriter("passengerResult.txt");
            BufferedWriter out = new BufferedWriter(fstream);
            out.write("LINE: "+routeName);
            out.newLine();
            out.newLine();
            int atime=firstOptimal.getDepoTime();
            String timef=fill("", DateValidation.getHour(atime) , DateValidation.getMinuts(atime));
            out.write("Departure:  "+timef +"   "+BusStopInfo.getFullName(firstOptimal.getStartStop()));
            out.newLine();
            out.newLine();
            int dtime=firstOptimal.getArrivalTime();
            String timed=fill("", DateValidation.getHour(dtime) , DateValidation.getMinuts(dtime));
            out.write("Arrrival:  "+timed +"   "+BusStopInfo.getFullName(firstOptimal.getEndStop()));
            out.newLine();
            out.newLine();
            out.write("Number of middle bus stops:  "+firstOptimal.getNoOfBusStopsBetween());
            out.newLine();
            out.newLine();
            String routeName2=BusStopInfo.getRouteName(secondOptimal.getRoute());
            out.write("You need to chnge bus for LINE: "+ routeName2);
            int atime2=secondOptimal.getDepoTime();
            String timef2=fill("", DateValidation.getHour(atime2) , DateValidation.getMinuts(atime2));
            out.newLine();
            out.newLine();
            out.write("Departure:  "+timef2 +"   "+BusStopInfo.getFullName(secondOptimal.getStartStop()));
            out.newLine();
            out.newLine();
            int dtime2=secondOptimal.getArrivalTime();
            String timed2=fill("", DateValidation.getHour(dtime2) , DateValidation.getMinuts(dtime2));
            out.write("Arrrival:  "+timed2 +"   "+BusStopInfo.getFullName(secondOptimal.getEndStop()));
            out.newLine();
            out.newLine();
            out.write("Number of middle bus stops:  "+secondOptimal.getNoOfBusStopsBetween());
            out.close();
        }
        catch (IOException e){//Catch exception if any
             System.err.println("Error: " + e.getMessage());
        }

    }




}


